package com.wry.spring.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.lang.reflect.Method;

/**
 * <h1> CgLib动态代理 </h1>
 *
 * @author wry
 * @since 2025.04.04
 */

public class CgLibProxy {

    public static void main(String[] args) {
        TrainStation trainStation = new TrainStation();
        TrainStationMethodInterceptor interceptor = new TrainStationMethodInterceptor(trainStation);
        TrainStation proxy = (TrainStation) interceptor.getProxy();
        proxy.issueTickets();
        proxy.issueTickets2();
    }


    /**
     * 车站  被代理对象
     */
    static class TrainStation{
        public void issueTickets() {
            System.out.println("我是车站-出票完成！");
        }

        public void issueTickets2() {
            System.out.println("我是车站2-出票完成！");
        }
    }

    /**
     * GgLib代理-代理（车站）
     */
    static class TrainStationMethodInterceptor implements MethodInterceptor {

        /**
         * 目标原始对象
         */
        private Object target;

        public TrainStationMethodInterceptor(Object target) {
            this.target = target;
        }

        /**
         * 获取代理对象
         * @return
         */
        public Object getProxy() {
            Enhancer enhancer = new Enhancer();
            // 设置父类(原始对象)
            enhancer.setSuperclass(target.getClass());
            // 设置回调函数
            enhancer.setCallback(this);
            // 创建代理对象
            return enhancer.create();
        }

        /**
         * 方法增强
         */

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            askForTickets();
            // 原始对象方法
//            Object invoke = method.invoke(target, objects);
            Object invoke = methodProxy.invokeSuper(o, objects);
            getTheTicket();
            return invoke;
        }

        public void askForTickets() {
            System.out.println("我是代理-询问使用车票吗？需要给我钱把");
            System.out.println("我是代理-还有余票啊！");
        }

        public void getTheTicket() {
            System.out.println("我是代理-帮你买到车票啦！付钱给车站");
        }
    }
}
